package com.ibl.rover.lite.service.sync.request.implementation;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.ibl.rover.lite.handler.AppSetupHandler;
import com.ibl.rover.lite.handler.CustomerHandler;
import com.ibl.rover.lite.handler.OrderHandler;
import com.ibl.rover.lite.handler.ProductCategoryHandler;
import com.ibl.rover.lite.handler.ProductHandler;
import com.ibl.rover.lite.handler.RouteHandler;
import com.ibl.rover.lite.service.utill.Core.COMMON_TAGS;
import com.ibl.rover.lite.service.utill.Core.SST_TAGS;
import com.ibl.rover.lite.service.utill.Core.USER_TAGS;
//import com.avanza.ssa.services.constants.ServicesConstants.HTMLCONSTANTS;
import com.ibl.rover.lite.service.utill.HibernateUtill;
import com.ibl.rover.lite.services.sync.request.ISyncRequest;
import com.rover.lite.hibernate.dal.RvrAppsetup;

public class SyncRequestHandler implements ISyncRequest {

	private Session session;
	DocumentBuilderFactory dFact = DocumentBuilderFactory.newInstance();
	DocumentBuilder build;
	Document doc;
	boolean isSuccessful = true;
	String responseCode = "404";
	public String userName, ResponseMessage;

	public SyncRequestHandler() {
		session = HibernateUtill.getSessionFactory().openSession();
	}

	@Override
	public String parseInput(String inputXml) {
		try {
			build = dFact.newDocumentBuilder();
			doc = build.newDocument();

			build = dFact.newDocumentBuilder();
			InputSource is = new InputSource(new StringReader(inputXml));
			doc = build.parse(is);

			// get the root element
			Element docEle = doc.getDocumentElement();
			Node headNode = docEle.getFirstChild();
			Node authNode = headNode.getFirstChild();
			org.w3c.dom.NodeList authnodes = authNode.getChildNodes();

			if (authnodes != null && authnodes.getLength() > 0) {

				// get the Authenticate Element
				Element el = (Element) authnodes.item(0);
				userName = el.getTextContent();
				return Integer.toString(authenicateUser());

				// if(authenicateUser()==1){
				//
				// Node sstNode = headNode.getLastChild();
				// if(sstNode!=null && sstNode.getChildNodes().getLength() > 0){
				// org.w3c.dom.NodeList sstNodeList = sstNode.getChildNodes();
				//
				// for (int index = 0; index < sstNodeList.getLength(); index++)
				// {
				// Element sstElement = (Element) sstNodeList.item(index);
				// String sstName =sstElement.getAttribute("name");
				// switch (sstName){
				// case SST_TAGS.SKU_TYPE:
				//
				//
				// break;
				// }
				//
				// }
				// }else{
				//
				// //It is Syns request Handle it...
				// }
				//
				//
				//
				// }else{
				//
				//
				// // NO User Found Create that Format
				// }
				//

			}

		} catch (Exception e) {
			// TODO: handle exception
			// System.out.println(e.getMessage());
			e.printStackTrace();
			isSuccessful = false;

		}
		return "0";
	}

	public String createRootXml(String inputXml) {
		try {
			build = dFact.newDocumentBuilder();

			doc = build.newDocument();
			Element rootElement = doc.createElement(COMMON_TAGS.SyncXml);
			doc.appendChild(rootElement);
			Element headElement = doc.createElement(COMMON_TAGS.head);
			rootElement.appendChild(headElement);

			Element bodyElement = doc.createElement(COMMON_TAGS.body);
			rootElement.appendChild(bodyElement);

			GetData(inputXml, bodyElement);

			setresponseCodeXMl(headElement);
			TransformerFactory tFact = TransformerFactory.newInstance();
			Transformer trans = null;
			trans = tFact.newTransformer();
			StringWriter writer = new StringWriter();
			StreamResult result = new StreamResult(writer);
			DOMSource source = new DOMSource(doc);
			trans.transform(source, result);
			return writer.toString();

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
			isSuccessful = false;
			return e.getMessage();
		}
	}

	public String unSuccessfulResponse() {
		try {
			build = dFact.newDocumentBuilder();

			doc = build.newDocument();
			Element rootElement = doc.createElement(COMMON_TAGS.SyncXml);
			doc.appendChild(rootElement);
			Element headElement = doc.createElement(COMMON_TAGS.head);
			rootElement.appendChild(headElement);
			setresponseCodeXMl(headElement);
			Element bodyElement = doc.createElement(COMMON_TAGS.body);
			rootElement.appendChild(bodyElement);

			TransformerFactory tFact = TransformerFactory.newInstance();
			Transformer trans = null;
			trans = tFact.newTransformer();
			StringWriter writer = new StringWriter();
			StreamResult result = new StreamResult(writer);
			DOMSource source = new DOMSource(doc);
			trans.transform(source, result);
			return writer.toString();

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
			isSuccessful = false;
			return e.getMessage();
		}

	}

	private void setresponseCodeXMl(Element headElement) {
		try {

			Element responseElement = doc
					.createElement(COMMON_TAGS.responseCode);
			headElement.appendChild(responseElement);
			if (isSuccessful)
				responseElement.setAttribute("value", "000");
			else
				responseElement.setAttribute("value", responseCode);

			Element responseMessage = doc
					.createElement(COMMON_TAGS.responseMessage);
			headElement.appendChild(responseMessage);
			if (isSuccessful)
				responseMessage.setAttribute("value", "Success!");
			else
				responseMessage.setAttribute("value", "Not Successful");

			Element userInfoElement = doc
					.createElement(USER_TAGS.TAG_USER_INFO);
			userInfoElement.setAttribute(USER_TAGS.USER_NAME, userName);

			headElement.appendChild(userInfoElement);

		} catch (Exception e) {

		}
	}

	private void GetData(String inputXml, Element bodyElement) {
		Document dom;
		try {
			InputSource is = new InputSource(new StringReader(inputXml));
			dom = build.parse(is);
			// get the root element
			Element docEle = dom.getDocumentElement();
			Node headNode = docEle.getFirstChild();

			Node sSTNode = headNode.getLastChild();

			Node sstNode = headNode.getLastChild();
			org.w3c.dom.NodeList sstNodeList = sstNode.getChildNodes();
			if (sstNode != null && sstNodeList.getLength() > 0) {

				for (int index = 0; index < sstNodeList.getLength(); index++) {
					Element sstElement = (Element) sstNodeList.item(index);
					Element emplyeeElement = (Element) sstNodeList.item(index);
					getEntity(emplyeeElement, bodyElement);
				}
			} else {

				// It is Syns request Handle it...
				Node bodyNode = docEle.getLastChild();
				org.w3c.dom.NodeList bodyNodeList = bodyNode.getChildNodes();

				for (int index = 0; index < bodyNodeList.getLength(); index++) {

					Element bodyNodeElement = (Element) bodyNodeList
							.item(index);
					Element emplyeeElement = (Element) bodyNodeList.item(index);
					getEntity(emplyeeElement, bodyElement);
				}
			}

			// LoginActionRequestHandler actionRequestHandler = new
			// LoginActionRequestHandler(
			// userName, imei);
			// actionRequestHandler.doAction(inputXml, entityElementMap);

		} catch (SAXException e) {
			isSuccessful = false;
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
			isSuccessful = false;
		}
	}

	private void getEntity(Element entityElement, Element bodyElement) {

		String name = entityElement.getAttribute("name");

		if (name.equals(SST_TAGS.APPSETUP)) {
			AppSetupHandler appSetupHandler = new AppSetupHandler(doc);
			appSetupHandler.getAppSetup(bodyElement, userName);
		} else if (name.equals(SST_TAGS.CUSTOMERS)) {
			CustomerHandler customerHandler = new CustomerHandler(doc);
			customerHandler.getCustomers(bodyElement, userName);
		} else if (name.equals(SST_TAGS.PRODUCT_CATEGORY)) {
			ProductCategoryHandler productCategoryHandler = new ProductCategoryHandler(
					doc);
			productCategoryHandler.getProductCategory(bodyElement, userName);
		} else if (name.equals(SST_TAGS.ROUTE)) {
			RouteHandler routeHandler = new RouteHandler(doc);
			routeHandler.getProductCategory(bodyElement, userName);
		} else if (name.equals(SST_TAGS.PRODUCT)) {
			ProductHandler productHandler = new ProductHandler(doc);
			productHandler.getProducts(bodyElement, userName);
		} else if (name.equals(SST_TAGS.ORDER)) {
			OrderHandler orderHandler = new OrderHandler(doc);
			CallOrderhandler(orderHandler, entityElement, bodyElement);
		}

//		switch (name.hashCode()) {
//		case (SST_TAGS.APPSETUP).hashCode():
//			AppSetupHandler appSetupHandler = new AppSetupHandler(doc);
//			appSetupHandler.getAppSetup(bodyElement, userName);
//			// getAppSetup(bodyElement);
//			break;
//
//		case (SST_TAGS.CUSTOMERS).hashCode():
//			CustomerHandler customerHandler = new CustomerHandler(doc);
//			customerHandler.getCustomers(bodyElement, userName);
//			// getCustomers(bodyElement);
//			break;
//
//		case (SST_TAGS.PRODUCT_CATEGORY).hashCode():
//			ProductCategoryHandler productCategoryHandler = new ProductCategoryHandler(
//					doc);
//			productCategoryHandler.getProductCategory(bodyElement, userName);
//			break;
//
//		case (SST_TAGS.ROUTE).hashCode():
//			RouteHandler routeHandler = new RouteHandler(doc);
//			routeHandler.getProductCategory(bodyElement, userName);
//			break;
//
//		case (SST_TAGS.PRODUCT).hashCode():
//			ProductHandler productHandler = new ProductHandler(doc);
//			productHandler.getProducts(bodyElement, userName);
//			break;
//
//		case (SST_TAGS.ORDER).hashCode():
//			OrderHandler orderHandler = new OrderHandler(doc);
//			CallOrderhandler(orderHandler, entityElement, bodyElement);
//			// boolean isCatch=false;
//			// session.beginTransaction();
//
//			break;
//
//		}
	}

	public void CallOrderhandler(OrderHandler orderHandler,
			Element entityElement, Element bodyElement) {
		try {
			boolean result = orderHandler.insertOrders(entityElement,
					bodyElement, userName);

			// session.getTransaction().commit();
			CreateMeassgeTag(bodyElement, result);
			isSuccessful = result;

		} catch (ParseException e) {
			// TODO Auto-generated catch block
			// isCatch=true;
			isSuccessful = false;
			e.printStackTrace();
			CreateMeassgeTag(bodyElement, false);
		} finally {

		}

	}

	public void CreateMeassgeTag(Element entityElement, boolean result) {

		Element attributeElement = doc.createElement("Message");
		entityElement.appendChild(attributeElement);

		if (result)
			attributeElement.setAttribute("Result", "Successful");
		else
			attributeElement.setAttribute("Result", "Not Successful");
	}

	@Override
	public int authenicateUser() {
		// TODO Auto-generated method stub

		List<RvrAppsetup> customer_list = new ArrayList<RvrAppsetup>();

		Session session = HibernateUtill.getSessionFactory().openSession();
		Criteria criteria = session.createCriteria(RvrAppsetup.class);

		criteria.add(Restrictions.eq("id.tsoCode", userName));
		customer_list = criteria.list();

		if (customer_list.size() > 0)
			return 1;

		isSuccessful = false;
		responseCode = "505";
		return 0;
	}

}
